Jersey-2.x-User-Guide

3.3. Sub-resources 子资源

@Path可以用在类,这样的类称为根资源类。也可以被用来根资源类的方法上。这使得许多资源被组合在一起,方法被重用。

第一种方法 @Path 是用在资源的方法,而这些方法是被称为子资源的方法。下面的例子显示一个方法从后端资源类jmaki签名验证的示例:

Example 3.17. 子资源方法

@Singleton
@Path("/printers")
public class PrintersResource {

    @GET
    @Produces({"application/json", "application/xml"})
    public WebResourceList getMyResources() { ... }

    @GET @Path("/list")
    @Produces({"application/json", "application/xml"})
    public WebResourceList getListOfPrinters() { ... }

    @GET @Path("/jMakiTable")
    @Produces("application/json")
    public PrinterTableModel getTable() { ... }

    @GET @Path("/jMakiTree")
    @Produces("application/json")
    public TreeModel getTree() { ... }

    @GET @Path("/ids/{printerid}")
    @Produces({"application/json", "application/xml"})
    public Printer getPrinter(@PathParam("printerid") String printerId) { ... }

    @PUT @Path("/ids/{printerid}")
    @Consumes({"application/json", "application/xml"})
    public void putPrinter(@PathParam("printerid") String printerId, Printer printer) { ... }

    @DELETE @Path("/ids/{printerid}")
    public void deletePrinter(@PathParam("printerid") String printerId) { ... }
}

如果请求URL的路径是 "printers" 然后资源的方法没有注明 @Path 将被选择。如果请求的URL请求的路径是"printers/list",首先根资源类将匹配,然后子资源相匹配的方法"list"将被选择,在这种情况下,子资源方法是 getlistofprinters 。因此,在这个例子中的 URL 路径将会分层匹配进行。

第二种用法 @Path 可能用在那些没有注明的资源指示器 像 @GET 或者 @POST的方法上。这种方法被称为子资源定位器。下面的示例显示一个根资源类和从乐观并发采样资源类的方法签名:

Example 3.18. 子资源定位器

@Path("/item")
public class ItemResource {
    @Context UriInfo uriInfo;

    @Path("content")
    public ItemContentResource getItemContentResource() {
        return new ItemContentResource();
    }

    @GET
    @Produces("application/xml")
        public Item get() { ... }
    }
}

public class ItemContentResource {

    @GET
    public Response get() { ... }

    @PUT
    @Path("{version}")
    public void put(@PathParam("version") int version,
                    @Context HttpHeaders headers,
                    byte[] in) {
        ...
    }
}

根类资源 ItemResource 包含子资源定位方法 getItemContentResource,用于返回一个新的资源类。如果请求URL的路径是"item/content",首先根资源将匹配,而后则子资源定位器将匹配和调用,它返回的 itemcontentresource 资源类的一个实例。子资源定位器使得资源类的能够重用。一种方法可以有空路径 @Path注解 (@Path("/") or @Path("")) 这意味着子资源定位器是用于封闭的资源路径匹配(无子资源的路径)。

Example 3.19. 空路径的子资源定位器

@Path("/item")
public class ItemResource {

    @Path("/")
    public ItemContentResource getItemContentResource() {
        return new ItemContentResource();
    }
}

此外,处理资源类的子资源定位器返回的是在运行时执行从而支持多态性。子资源定位器可能返回不同的子类型取决于请求(例如一次资源定位器可以返回不同的子类型取决于认证)。例如,下面的子资源定位器是有效的:

Example 3.20. 子资源定位器返回子类型

@Path("/item")
public class ItemResource {

    @Path("/")
    public Object getItemContentResource() {
        return new AnyResource();
    }
}

注意,运行时将没有生命周期管理或执行任何字段注入到子资源定位方法返回的实例。这是因为运行时不知道实例的生命周期是什么。如果必需要运行库管理子资源作为资源类标准,类应按以下示例返回:

Example 3.21. 从类中创建子资源定位器

import javax.inject.Singleton;

@Path("/item")
public class ItemResource {
    @Path("content")
    public Class<ItemContentSingletonResource> getItemContentResource() {
        return ItemContentSingletonResource.class;
    }
}

@Singleton
public class ItemContentSingletonResource {
    // this class is managed in the singleton life cycle
}

JAX-RS 资源默认情况下,在每个请求范围受到管理,这意味着为每个请求创建新的资源。在这个例子中,javax.inject.Singleton 是说,资源将是单例模式,不受请求范围管理。子资源定位方法返回一个类,这意味着运行时将托管资源的实例及其生命周期。相反,如果方法返回的是实例,那么注释将没有效果,返回的实例将被使用。

子资源定位器也可以返回一个 a programmatic resource model (可编程的资源模型)。更多关于可编程资源模型的构建,请看 resource builder section。下面的示例显示子资源定位方法返回的非常简单的资源。

Example 3.22. 子资源定位返回资源模型

import org.glassfish.jersey.server.model.Resource;

@Path("/item")
public class ItemResource {

    @Path("content")
    public Resource getItemContentResource() {
        return Resource.from(ItemContentSingletonResource.class);
    }
}

上面的代码为之前的例子有同样的效果。资源是一种资源的简单的资源由ItemContentSingletonResource 构造。更复杂的编程资源也可以返回只要它们是有效的资源。